function debounce(fn, delay, immediate, resultCallback) {
  let timer = null
  let flag = true
  function _debounce(...args) {
    if (timer) clearTimeout(timer)
    if (immediate && flag) {
      let result = fn.apply(this, ...args)
      if (result) resultCallback(result)
      flag = false
    } else {
      timer = setTimeout(() => {
        let result = fn.apply(this, ...args)
        if (result) resultCallback(result)
        flag = true
      }, delay)
    }
  }
  _debounce.cancel = function () {
    if (timer) clearTimeout(timer)
    timer = null
    flag = false
  }
  return _debounce
}